package com.ap.core.jbehave.confirmpayment;

import org.jbehave.core.annotations.Given;
import org.jbehave.core.annotations.Then;
import org.jbehave.core.annotations.When;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ap.core.cxf.jaxb.common.DeliveryType;
import com.ap.core.cxf.jaxb.managepayment.ConfirmPayment1Request;
import com.ap.core.cxf.jaxb.managepayment.ConfirmPayment1Response;
import com.ap.core.cxf.jaxb.managepayment.RetrieveRTP1Request;
import com.ap.core.cxf.jaxb.managepayment.RetrieveRTP1Response;
import com.ap.core.cxf.jaxb.managertp.SubmitRTP1Request;
import com.ap.core.cxf.jaxb.managertp.SubmitRTP1Response;
import com.ap.core.cxf.jaxb.managertp.SubmitRTPMessageType;
import com.ap.core.cxf.jaxb.msghdr.MessageType;
import com.ap.core.cxf.jaxb.rtp.TransactionCheckOutType;
import com.ap.core.jbehave.BaseTransitionRTPSteps;
import com.ap.core.jbehave.StoryContext;
import com.ap.core.util.JaxbUtil;
import com.ap.core.util.Nullable;
import com.ap.core.util.TypedKey;
import com.core.ap.wsdl.managepaymentservice_1.ManagePayment1PortType;
import com.core.ap.wsdl.managertpservice_1.ManageRTP1PortType;

public class ConfirmPaymentMobDeliverySteps extends BaseTransitionRTPSteps {

	private static final TypedKey<Nullable<SubmitRTP1Response>> SUBMIT_RTP_RESPONSE = new TypedKey<>(
			"SubmitRTPResponseType");
	private static final TypedKey<Nullable<RetrieveRTP1Response>> RETRIEVE_RTP_RESPONSE = new TypedKey<>(
			"RetreiveRTPResponseType");
	private static final TypedKey<Nullable<ConfirmPayment1Response>> CONFIRM_PAYMENT_RESPONSE = new TypedKey<>(
			"ConfirmPaymentResponseType");

	private SubmitRTP1Request submitRTPRequest;
	private RetrieveRTP1Request retrieveRTPRequest;
	private ConfirmPayment1Request confirmPayment1Request;

	private static final Logger LOG = LoggerFactory
			.getLogger(ConfirmPaymentSteps.class);

	public ConfirmPaymentMobDeliverySteps(StoryContext storyContext) {
		super(storyContext);
	}

	@Given("the consumer Bank successfully completed a Faster Payment transaction to the Distributor/Merchant for the value of the purchase using m-com")
	public void giveBankCompletedMComPayment() throws Exception {

		final ManageRTP1PortType singnedPort = factory
				.getBean(ManageRTP1PortType.class);
		submitRTPRequest = createSubmitRTPRequest(SubmitRTPMessageType.SUBMITRTPFORMOB);
		submitRTPRequest.getRTPSummary().setTxCheckout(
				TransactionCheckOutType.NRMLCHK);
		submitRTPRequest.getRTPSenderInfo().getDistributorInfo()
				.setDistributorId("000001");
		submitRTPRequest.getRTPSenderInfo().getDetailMerchantInfo()
				.getMerchantInfo().setMerchantId("000001");
		submitRTPRequest.getDelivery().setDeliveryType(DeliveryType.COLLST);

		LOG.info("Given -  the consumer Bank successfully completed a Faster Payment transaction to the Distributor/Merchant for the value of the purchase using m-com");
		JaxbUtil.newInstance().javaToXML(SubmitRTP1Request.class,
				submitRTPRequest);

		SubmitRTP1Response responseRTPType = singnedPort
				.submitRTP1(submitRTPRequest);

		JaxbUtil.newInstance().javaToXML(SubmitRTP1Response.class,
				responseRTPType);

		storyContext.put(SUBMIT_RTP_RESPONSE,
				Nullable.nullable(responseRTPType));

		final ManagePayment1PortType managePaymentSignedPort = factory
				.getBean(ManagePayment1PortType.class);
		retrieveRTPRequest = createRetrieveRTPRequest();
		retrieveRTPRequest.getRequestInfo().setApTransactionId(
				responseRTPType.getResponseInfo().getApTransactionId());
		retrieveRTPRequest.getRequestInfo().setApTRId(responseRTPType.getResponseInfo().getApTRId());
		retrieveRTPRequest.getRequestInfo().setFIId("000002");
		retrieveRTPRequest.getRequestInfo().setFIConsumerId("hsbccon2");
		retrieveRTPRequest.getRequestInfo().setBRN(null);

		JaxbUtil.newInstance().javaToXML(RetrieveRTP1Request.class,
				retrieveRTPRequest);
		RetrieveRTP1Response retrieveRTPResponse = managePaymentSignedPort
				.retrieveRTP1(retrieveRTPRequest);

		JaxbUtil.newInstance().javaToXML(RetrieveRTP1Response.class,
				retrieveRTPResponse);

		storyContext.put(RETRIEVE_RTP_RESPONSE,
				Nullable.nullable(retrieveRTPResponse));				
	}

	@When("AP Server receives the Payment Confirmation from Consumer's Bank")
	public void whenAPReceivesPaymentConfirmation() throws Exception {
		
		final ManagePayment1PortType managePayment1PortType = factory
				.getBean(ManagePayment1PortType.class);

		Nullable<RetrieveRTP1Response> retrieveRTPResponse = storyContext
				.get(RETRIEVE_RTP_RESPONSE);

		confirmPayment1Request = createConfirmPayment1Request(MessageType.CONFIRMPAYMENT, TransactionCheckOutType.NRMLCHK , submitRTPRequest.getDelivery().getDeliveryType());

		confirmPayment1Request.getPaymtDetails().setApTransactionId(
				retrieveRTPRequest.getRequestInfo().getApTransactionId());
		
		confirmPayment1Request.getPaymtDetails().setApTRId(retrieveRTPResponse.value().getRTPIdentifier().getApTRId());

		confirmPayment1Request.getConsumerAcct().setFIId(
				retrieveRTPResponse.value().getConsumerInfo().getFIId());

		confirmPayment1Request.getPaymtDetails().getPaymentStatusInfo().setTotalPaymentReqAmount(retrieveRTPResponse.value().getRTPSummary().getPaymtAmtInfo().getTotalPaymentReqAmount());
		
		JaxbUtil.newInstance().javaToXML(ConfirmPayment1Request.class,
				confirmPayment1Request);
		LOG.info("When -  APCore receives the structurally valid CONFIRMPAYMENT request from OSB");
		ConfirmPayment1Response confirmPayment1Response = managePayment1PortType
				.confirmPayment1(confirmPayment1Request);

		JaxbUtil.newInstance().javaToXML(ConfirmPayment1Response.class,
				confirmPayment1Response);

		storyContext.put(CONFIRM_PAYMENT_RESPONSE,
				Nullable.nullable(confirmPayment1Response));		
	}

	@Then("AP Server sends Payment Notification to the Distributor/Merchant")
	public void thenAPSendsPaymentNotification() {		
		doConfirmPaymentResponseAssertions(storyContext.get(CONFIRM_PAYMENT_RESPONSE), confirmPayment1Request, submitRTPRequest);

		LOG.info("Test executed successfully...");
	}
}
